package org.bob.web.controller;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.GeoLocation;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import lombok.extern.slf4j.Slf4j;
import org.bob.web.model.SearchRes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
public class GeoController extends BaseController{

    @Autowired
    private ElasticsearchClient elasticsearchClient;

    @GetMapping("/geoDistance")
    public Mono<SearchRes> geoDistance(){
        SearchRequest searchRequest = SearchRequest.of(s->s.index("hotel").query(q->q.geoDistance(m->m.field("location").distance("50km").location(aa->aa.text("39.58,116.49")))));
        SearchResponse<Object> search;
        try {
            search = elasticsearchClient.search(searchRequest, Object.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return toMono(search);
    }

    @GetMapping("/geoBoundingBox")
    public Mono<SearchRes> geoBoundingBox(){
        SearchRequest searchRequest = SearchRequest.of(s->s.index("hotel").query(q->q.geoBoundingBox(m->m.field("location").boundingBox(aa->aa.coords(bb->bb.top(40).bottom(39).left(116.40).right(117))))));
        SearchResponse<Object> search;
        try {
            search = elasticsearchClient.search(searchRequest, Object.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return toMono(search);
    }


    /*@GetMapping("/geoShape")
    public Mono<SearchRes> geoShape(){
        List<GeoLocation> list = new ArrayList<>();
        list.add(new GeoLocation.Builder().text("39.58,116.39").build());
        list.add(new GeoLocation.Builder().text("39.28,116.49").build());
        list.add(new GeoLocation.Builder().text("39.48,116.59").build());

        SearchRequest searchRequest = SearchRequest.of(s->s.index("hotel").query(q->q.geoShape(m->m.field("location").shape(aa->aa.relation(list)))));
        SearchResponse<Object> search;
        try {
            search = elasticsearchClient.search(searchRequest, Object.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return toMono(search);
    }*/

    @GetMapping("/geoPolygon")
    public Mono<SearchRes> geoPolygon(){
        List<GeoLocation> list = new ArrayList<>();
        list.add(new GeoLocation.Builder().text("39.58,116.39").build());
        list.add(new GeoLocation.Builder().text("39.28,116.49").build());
        list.add(new GeoLocation.Builder().text("39.48,116.59").build());

        SearchRequest searchRequest = SearchRequest.of(s->s.index("hotel").query(q->q.geoPolygon(m->m.field("location").polygon(aa->aa.points(list)))));
        SearchResponse<Object> search;
        try {
            search = elasticsearchClient.search(searchRequest, Object.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return toMono(search);
    }
}
